package org.example.nebula.service;

import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.example.nebula.entity.input.ExportEdgeInput;
import org.example.nebula.entity.input.ExportNodeInput;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: jszhang
 * @date: 2025/10/26-11:43
 */
@Slf4j
@Service
public class ExportDataService {

    @Resource
    private CommonService commonService;

    public void exportNode2Csv(ExportNodeInput input) {
        log.info("开始-->{}", input.getNodeName());

        StringBuilder sqlStrBuilder = new StringBuilder();
        sqlStrBuilder.append("USE " + input.getSpaceName() + ";");
        sqlStrBuilder.append("MATCH (n:" + input.getNodeName() + ") RETURN n");
//        sqlStrBuilder.append(" Limit 10");

        JSONArray data = commonService.executeJson(sqlStrBuilder.toString());
        JSONArray array = data.getJSONObject(0).getJSONArray("data");

        List<String> titleList = new ArrayList<>();
        titleList.add("id");
        List<String> lineInfo = new ArrayList<>();
        for (int i = 0; i < array.size(); i++) {
            List<String> lineList = new ArrayList<>();
            JSONArray meta = array.getJSONObject(i).getJSONArray("meta");
            String nodeId = meta.getJSONObject(0).getStr("id");
            lineList.add(nodeId);

            JSONArray row = array.getJSONObject(i).getJSONArray("row");
            JSONObject nodeJson = row.getJSONObject(0);
            if (i == 0) {
                titleList.addAll(nodeJson.keySet());
                lineInfo.add(String.join("->", titleList));
            }

            for (String key : titleList) {
                if (nodeJson.containsKey(key)) {
                    lineList.add(nodeJson.getStr(key));
                }
            }
            lineInfo.add(String.join("->", lineList));
        }

        if (!FileUtil.exist(input.getCsvPath())) {
            FileUtil.mkdir(input.getCsvPath());
        }

        FileUtil.writeLines(lineInfo, input.getCsvPath() + input.getNodeName() + ".txt", StandardCharsets.UTF_8);

        log.info("结束-->{},共计{}个", input.getNodeName(), lineInfo.size());
    }

    public void exportEdge2Csv(ExportEdgeInput input) {
        log.info("开始-->{}", input.getEdgeName());

        StringBuilder sqlStrBuilder = new StringBuilder();
        sqlStrBuilder.append("USE " + input.getSpaceName() + "; ");
        sqlStrBuilder.append("MATCH()-[e:" + input.getEdgeName() + "]->() RETURN e");
//        sqlStrBuilder.append(" LIMIT 10");

        JSONArray data = commonService.executeJson(sqlStrBuilder.toString());
        JSONArray array = data.getJSONObject(0).getJSONArray("data");

        List<String> titleList = new ArrayList<>();
        titleList.add("src");
        titleList.add("dst");
        List<String> lineInfo = new ArrayList<>();
        for (int i = 0; i < array.size(); i++) {
            JSONObject meta = array.getJSONObject(i).getJSONArray("meta").getJSONObject(0);
            JSONObject proJson = array.getJSONObject(i).getJSONArray("row").getJSONObject(0);

            String src = meta.getJSONObject("id").getStr("src");
            String dst = meta.getJSONObject("id").getStr("dst");
//            int ranking = meta.getJSONObject("id").getInt("ranking");

            if (i == 0) {
                titleList.addAll(proJson.keySet());
                lineInfo.add(String.join("->", titleList));
            }
            List<String> lineList = new ArrayList<>();
            lineList.add(src);
            lineList.add(dst);

            for (String key : titleList) {
                if (proJson.containsKey(key)) {
                    lineList.add(proJson.getStr(key));
                }
            }
            lineInfo.add(String.join("->", lineList));
        }


        if (!FileUtil.exist(input.getCsvPath())) {
            FileUtil.mkdir(input.getCsvPath());
        }

        FileUtil.writeLines(lineInfo, input.getCsvPath() + input.getEdgeName() + ".txt", StandardCharsets.UTF_8);

        log.info("结束-->{},共计{}条", input.getEdgeName(), lineInfo.size());
    }

}
